﻿using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.UI;

public class AdditionManager : MonoSingleton<AdditionManager> {
    [Header("Share")]
    public PlayableDirector playableDirector;
    public LeDiController lediController;
    public RectTransform panelHonour;
    public Transform spawnParent;
    public Transform sceneParent;
    public Transform postionGroup;
    public RectTransform honour;
    public Transform effect;
    public Camera uiCamera;
    public float sheepRunTime = 2f;
    public float uiScaleValue = 1.2f;

    [Header("Level 1")]
    public RectTransform panelExpL1;
    public Text leftL1;
    public Text rightL1;
    public Text plusL1;
    public Text equalL1;
    public Text sumL1;
    public RectTransform[] answersL1;

    [Header("Level 2")]
    public RectTransform panelWoolL2;
    public RectTransform panelExpL2;
    public RectTransform wool;
    public Text leftL2;
    public Text rightL2;
    public Text sumL2;
    public Text num;
    public Image plusL2;
    public Image equalL2;
    public List<Image> wools;
    public RectTransform[] answersL2;
    

    public static AdditionExpression CurrentAE { get; private set; }

    List<AdditionExpression> _listAE;
    Dictionary<Vector3, List<Vector3>> _dict;
    List<Vector3> _leftKeys;
    List<Vector3> _rightKeys;
    Dictionary<Vector3, int> _trackDirection;
    Texture2D _sheepGrayTexture;
    int _cycleTimeLevel_1 = 4;  // 4
    int _initSheepCount = 9;    // 9

    enum LevelState {
        Level_1,
        Level_2,
        Level_3,
    }

    LevelState _currentLevelState = LevelState.Level_1;

    void Start() {
        if (playableDirector == null) {
            playableDirector = GetComponent<PlayableDirector>();
        }

        AudioManager.Instance.PlayMusic(AdditionResPath.BGM_601010112, true, true);

        _dict = new Dictionary<Vector3, List<Vector3>>();
        _leftKeys = new List<Vector3>();
        _rightKeys = new List<Vector3>();
        _trackDirection = new Dictionary<Vector3, int>();
        _sheepGrayTexture = CommonUtility.LoadTexture(AdditionResPath.TEX_SHEEP_GRAY);
        _listAE = new List<AdditionExpression>();

        ResetDict();

        CommonUtility.InstantiateFrom(AdditionResPath.SCENE_1, sceneParent);
        playableDirector.playableAsset = CommonUtility.LoadTimeline(AdditionResPath.TL_ADDITION);
        playableDirector.Play();

        SheepController.IsShear = false;
    }

    public void StartLevel_1(float duration) {
        _currentLevelState = LevelState.Level_1;
        PauseTimeline(duration);
        ShowPanelExpL1();
        SDKManager.Instance.Event(UmengEvent.AddMianYang);
        SDKManager.Instance.StartLevel(UmengLevel.AddMianYang);
    }

    public void StartLevel_2(float duration) {
        _currentLevelState = LevelState.Level_2;
        PauseTimeline(duration);
        ShowSheep(_initSheepCount);
        StartCoroutine(TimeUtility.DelayInvoke(sheepRunTime, () => {
            PlayTimeline();
            SheepController.IsShear = true;
            panelWoolL2.SetActive(true);
        }));
        SDKManager.Instance.FinishLevel(UmengLevel.AddMianYang);
        SDKManager.Instance.Event(UmengEvent.AddYangMao);
        SDKManager.Instance.StartLevel(UmengLevel.AddYangMao);
    }

    public void StartLevel_3(float duration) {
        _currentLevelState = LevelState.Level_3;
        PauseTimeline(duration);
        ShowCarAndBox();
        panelHonour.SetActive(true);
        SheepController.IsShear = false;
        SDKManager.Instance.FinishLevel(UmengLevel.AddYangMao);
        SDKManager.Instance.Event(UmengEvent.AddCar);
        SDKManager.Instance.StartLevel(UmengLevel.AddCar);
    }

    public void OnExit() {
        switch (_currentLevelState) {
            case LevelState.Level_1:
                SDKManager.Instance.FinishLevel(UmengLevel.AddMianYang);
                break;
            case LevelState.Level_2:
                SDKManager.Instance.FinishLevel(UmengLevel.AddYangMao);
                break;
            case LevelState.Level_3:
                SDKManager.Instance.FinishLevel(UmengLevel.AddCar);
                break;
        }

        GameStateManager.Instance.GotoState(GameStateName.MAIN_STATE);
    }

    void SetCurrentAE() {
        var tempAE = AdditionExpression.RandomWithinTen();

        foreach (var ae in _listAE) {
            if ((ae.LeftValue == tempAE.LeftValue) && (ae.RightValue == tempAE.RightValue)) {
                SetCurrentAE();
                return;
            }
        }

        CurrentAE = tempAE;
        _listAE.Add(tempAE);
    }

    Transform _carAndBox;
    Transform _box;
    BoxController[] _boxControllers;
    CarController _carController;

    public void ShowCarAndBox() {
        SetCurrentAE();

        if (_carAndBox == null) {
            _carAndBox = CommonUtility.InstantiateFrom(AdditionResPath.CAR_AND_BOX, null);
            _carController = _carAndBox.GetComponentInChildren<CarController>();
            _box = _carAndBox.Find("Box");
            _boxControllers = _box.GetComponentsInChildren<BoxController>();
        }

        _carAndBox.localPosition = Vector3.right * -800f;
        _box.localPosition = Vector3.forward * 300f;
        _box.localScale = Vector3.one;

        foreach (var bc in _boxControllers) {
            bc.Reset();
        }

        var list = GetRandomAnswers();
        
        foreach (var bc in _boxControllers) {
            var index = Random.Range(0, list.Count);
            bc.SetSumValue(list[index]);
            list.RemoveAt(index);
        }

        _carController.SetLeftValue(CurrentAE.LeftValue);
        _carController.SetRightValue(CurrentAE.RightValue);
        _carController.transform.Find("Effect").SetActive(true);
       
        _carAndBox.DOMoveX(0f, 1f).OnComplete(() => {
            AudioManager.Instance.PlaySound(AdditionResPath.SE_CAR_STOP);
            _carController.ToAnimStop();
            _carController.transform.Find("Effect").SetActive(false);
            AudioManager.Instance.PlaySound(AdditionResPath.SE_SHOW_HIDE);
            _carAndBox.Find("Box").DOMoveZ(80f, 0.2f);
            
        });
    }

    public void HideCarAndBox() {
        _box.localScale = Vector3.zero;
        PlayHonourAnimation(() => {
            AudioManager.Instance.PlaySound(AdditionResPath.SE_CAR_MOVE);
            _carController.ToAnimMove();
            _carController.transform.Find("Effect").SetActive(true);
            _carAndBox.DOMoveX(800f, 1f).OnComplete(() => {
                StartCoroutine(TimeUtility.DelayInvoke(1.5f, () => {
                    if (_currentHonourCount >= _cycleTimeLevel_1) {
                        _currentHonourCount = 0;
                        panelHonour.SetActive(false);
                        ResetPanelHonour();
                        StartCoroutine(TimeUtility.DelayInvoke(sheepRunTime, PlayTimeline));
                    } else {
                        ShowCarAndBox();
                    }
                }));
            });
        });
    }

    public void ShowWoolAndNum(Vector3 position) {
        var screenPos = sceneParent.GetComponentInChildren<Camera>().WorldToScreenPoint(position);
        Vector3 worldPos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(wool, screenPos, uiCamera, out worldPos);
        wool.position = worldPos;
        wool.SetActive(true);
        AudioManager.Instance.PlaySound(AdditionResPath.SE_WOOL_MOVE);
        var endPos = panelWoolL2.Find("Scroll View").position;
        wool.DOMove(endPos, 0.5f).OnComplete(() => {
            var index = wools.Count - 1;
            wools[index].rectTransform.SetActive(true);
            wools.RemoveAt(index);
            num.rectTransform.SetActive(true);
            var count = int.Parse(num.text) + 1;
            StartCoroutine(TimeUtility.DelayInvoke(AudioManager.Instance.PlaySound(GetNumVoicePath(count)).Length, () => {
                if (count >= _initSheepCount) {
                    num.rectTransform.SetActive(false);
                    panelWoolL2.SetActive(false);
                    StartCoroutine(TimeUtility.DelayInvoke(sheepRunTime, () => ShowPanelExpL2()));
                }
            }));
            num.text = count.ToString();
            wool.SetActive(false);
        });
    }

    public void PauseTimeline(float duration) {
        playableDirector.Pause();
        playableDirector.time += duration;
        playableDirector.playableGraph.Destroy();
    }

    public void PlayTimeline() {
        playableDirector.Evaluate();
        playableDirector.Play();
    }

    public bool IsTimelinePlaying() {
        return playableDirector.state.Equals(PlayState.Playing);
    }

    public void ResetDict() {
        _dict.Clear();
        _leftKeys.Clear();
        _rightKeys.Clear();
        _trackDirection.Clear();

        for (var i = 0; i < postionGroup.childCount; i++) {
            var row = postionGroup.GetChild(i);
            var cols = new List<Vector3>();

            for (var j = 0; j < row.childCount; j++) {
                cols.Add(row.GetChild(j).position);
            }

            _dict.Add(row.position, cols);

            if (i < 2) {
                _rightKeys.Add(row.position);
            } else {
                _leftKeys.Add(row.position);
            }

            // 奇数行从左往右（1），偶数行从右往左（-1）
            if (i % 2 == 0) {
                _trackDirection.Add(row.position, -1);
            } else {
                _trackDirection.Add(row.position, 1);
            }
        }
    }

    public void ShowPanelExpL1(bool rewind = false) {
        if (rewind) {
            panelExpL1.DOAnchorPosY(200f, 0.5f);
        } else {
            ResetDict();
            RefreshExp(leftL1, rightL1, answersL1, true);
            panelExpL1.DOAnchorPosY(0f, 0.5f).OnComplete(() => PlayVoiceLeft(leftL1.rectTransform, plusL1.rectTransform, rightL1.rectTransform, true));
            sumL1.text = "?";
        }
    }

    public void ShowPanelExpL2(bool rewind = false) {
        if (rewind) {
            panelExpL2.DOAnchorPosY(77f, 0.5f);
        } else {
            panelHonour.SetActive(true);
            RefreshExp(leftL2, rightL2, answersL2, false);
            sumL2.text = CurrentAE.Sum.ToString();
            panelExpL2.DOAnchorPosY(-530f, 0.5f).OnComplete(() => PlayVoiceLeft(leftL2.rectTransform, plusL2.rectTransform, rightL2.rectTransform, false));
        }
    }

    public void OnDragComplete() {
        StartCoroutine(TimeUtility.DelayInvoke(1f, () => {
            ShowPanelAnswerL2(true);
            PlayHonourAnimation(() => {
                if (_currentHonourCount >= _cycleTimeLevel_1) {
                    _currentHonourCount = 0;
                    ShowPanelExpL2(true);
                    panelHonour.SetActive(false);
                    ResetPanelHonour();
                    StartCoroutine(TimeUtility.DelayInvoke(2f, () => {
                        PlayTimeline();
                    }));
                } else {
                    ShowPanelExpL2();
                }
            });
        }));
    }

    public void ShowClap(float duration) {
        PauseTimeline(duration);
        lediController.ActiveEffect(true);
    }

    public void RefreshExp(Text left, Text right, RectTransform[] answers, bool sumIsText) {
        SetCurrentAE();

        left.text = CurrentAE.LeftValue.ToString();
        right.text = CurrentAE.RightValue.ToString();

        if (sumIsText) {
            var list = GetRandomAnswers();

            foreach (var rt in answers) {
                var index = Random.Range(0, list.Count);
                var sum = list[index].ToString();
                rt.GetComponent<Text>().text = sum;
                list.RemoveAt(index);
            }
        } else {
            var list = new List<int>(new int[] { CurrentAE.LeftValue, CurrentAE.RightValue, CurrentAE.Sum });
           
            foreach (var rt in answers) {
                var index = Random.Range(0, list.Count);
                var sum = list[index].ToString();

                for (var i = 0; i < rt.childCount; i++) {
                    var child = rt.GetChild(i);
                    child.SetActive(child.name.Equals(sum));
                }

                list.RemoveAt(index);
            }
        }
    }

    public void RefreshRandomAnswers() {
        var list = GetRandomAnswers();

        foreach (var sum in answersL2) {
            var index = Random.Range(0, list.Count);
            var name = list[index].ToString();

            list.RemoveAt(index);
        }
    }

    List<int> GetRandomAnswers() {
        var list = new List<int>();
        list.Add(CurrentAE.Sum);

        while (list.Count < 3) {
            var sum = Random.Range(2, 10);

            if (!list.Contains(sum)) {
                list.Add(sum);
            }
        }

        return list;
    }

    public void OnClick(RectTransform rt) {
        var sum = int.Parse(rt.GetChild(0).GetComponent<Text>().text);

        if (sum == CurrentAE.Sum) {
            rt.GetComponent<Button>().interactable = false;
            rt.parent.Find("Image").SetActive(true);

            sumL1.rectTransform.DOLocalRotate(Vector3.up * 360f, 0.5f).OnComplete(() => {
                var path = GetNumVoicePath(CurrentAE.Sum);
                var voiceSum = AudioManager.Instance.PlaySound(path);
                StartCoroutine(TimeUtility.DelayInvoke(voiceSum.Length, () => {
                    StartCoroutine(TimeUtility.DelayInvoke(AudioManager.Instance.PlaySound(AdditionResPath.VOICE_SELECT_CORRECT).Length, () => {
                        ShowPanelExpL1(true);
                        ShowPanelAnswerL1(true);
                        DestroySheep();
                        PlayHonourAnimation(() => {
                            if (_currentHonourCount >= _cycleTimeLevel_1) {
                                _currentHonourCount = 0;
                                panelHonour.SetActive(false);
                                ResetPanelHonour();
                                PlayTimeline();
                            } else {
                                rt.GetComponent<Button>().interactable = true;
                                rt.parent.Find("Image").SetActive(false);
                                ShowPanelExpL1();
                            }
                        });
                    }));
                }));
            });

            sumL1.text = sum.ToString();
        } else {
            var animator = rt.GetComponent<Animator>();
            animator.Play("Shake", -1, 0f);
            AudioManager.Instance.PlaySound(AdditionResPath.SE_ERROR);
        }
    }

    void ResetPanelHonour() {
        foreach (RectTransform child in panelHonour) {
            if (!child.name.Equals("BG")) {
                child.GetComponent<Image>().sprite = CommonUtility.GetCommonSprite("xunzhang02");
            }
        }
    }

    public void ToLevel_2(float duration) {
        PauseTimeline(duration);

        TransitionManager.Instance.StartTransition(() => {
            _listAE.Clear();
            sceneParent.GetChild(0).Find("Camera_Level_1").SetActive(false);
            sceneParent.GetChild(0).Find("Camera_Level_2").SetActive(true);
            postionGroup.localPosition += Vector3.forward * 200f;
        },
        () => {
            PlayTimeline();
        });
    }

    public void ToLevel_3(float duration) {
        PauseTimeline(duration);

        TransitionManager.Instance.StartTransition(() => {
            _listAE.Clear();
            Destroy(sceneParent.GetChild(0).gameObject);
            CommonUtility.InstantiateFrom(AdditionResPath.SCENE_2, sceneParent);
        },
        () => {
            PlayTimeline();
        });
    }

    int _currentHonourCount = 0;

    void PlayHonourAnimation(System.Action callback) {
        StartCoroutine(TimeUtility.DelayInvoke(1f, () => {
            honour.anchoredPosition = Vector2.zero;
            honour.localScale = Vector3.zero;
            honour.SetActive(true);
            effect.localPosition = Vector3.forward * 100f;
            effect.localScale = Vector3.zero;
            effect.SetActive(true);

            AudioManager.Instance.PlaySound(AdditionResPath.SE_STAR);

            foreach (Transform t in effect) {
                t.DOScale(Vector3.one * 5f, 0.5f);
            }

            honour.DOScale(Vector3.one * 5f, 0.5f).OnComplete(() => {
                var child = panelHonour.GetChild(_currentHonourCount + 1);
                var endPos = (child as RectTransform).position;
                honour.DOMove(endPos, 1f);
                effect.DOMove(endPos, 1f);

                foreach (Transform t in effect) {
                    t.DOScale(Vector3.one, 1f);
                }

                honour.DOScale(Vector3.one, 1f).OnComplete(() => {
                    child.GetComponent<Image>().sprite = CommonUtility.GetCommonSprite("xunzhang");
                    honour.SetActive(false);
                    effect.SetActive(false);
                    AdsManager.Instance.ShowAds(AdsNameConst.Ads_Xunzhang);

                    if (callback != null) {
                        callback();
                    }
                });

                _currentHonourCount += 1;
            });
        }));
    }

    public void ShowPanelAnswerL1(bool rewind = false) {
        AudioManager.Instance.PlaySound(AdditionResPath.SE_SHOW_HIDE);
        var rt = answersL1[0].parent.parent.parent as RectTransform;

        if (rewind) {
            rt.DOAnchorPosY(0f, 0.1f);
        } else {
            rt.DOAnchorPosY(289f, 0.1f);
        }
    }

    public void ShowPanelAnswerL2(bool rewind = false) {
        AudioManager.Instance.PlaySound(AdditionResPath.SE_SHOW_HIDE);
        var rt = answersL2[0].parent.parent as RectTransform;

        if (rewind) {
            foreach (var child in answersL2) {
                child.GetComponent<Image>().raycastTarget = true;
                child.SetActive(false);
                child.anchoredPosition = Vector2.zero;
            }

            rt.DOAnchorPosY(0f, 0.1f);
        } else {
            foreach (var child in answersL2) {
                child.SetActive(true);
            }

            rt.DOAnchorPosY(310f, 0.1f).OnComplete(() => DragBoxUI.PlayAllAnimShake());
        }
    }

    public void PlayVoiceLeft(RectTransform rtLeft, RectTransform rtPlus, RectTransform rtRight, bool isShowSheep) {
        var path = GetNumVoicePath(CurrentAE.LeftValue);
        var duration = AudioManager.Instance.PlaySound(path).Length;
        ScaleUI(rtLeft, duration);
        StartCoroutine(TimeUtility.DelayInvoke(duration, () => {
            if (isShowSheep) {
                ShowSheep(true);
            } else {
                PlayVoiceRight(rtPlus, rtRight, isShowSheep);
            }
        }));
    }

    public void PlayVoiceRight(RectTransform rtPlus, RectTransform rtRight, bool isShowSheep) {
        var duration = AudioManager.Instance.PlaySound(AdditionResPath.VOICE_OPERATOR_PLUS).Length;
        ScaleUI(rtPlus, duration);

        StartCoroutine(TimeUtility.DelayInvoke(duration, () => {
            var path = GetNumVoicePath(CurrentAE.RightValue);
            var time = AudioManager.Instance.PlaySound(path).Length;
            ScaleUI(rtRight, time);
            StartCoroutine(TimeUtility.DelayInvoke(time, () => {
                if (isShowSheep) {
                    ShowSheep(false);
                } else {
                    var equalDuration = AudioManager.Instance.PlaySound(AdditionResPath.VOICE_OPERATOR_EQUAL).Length;
                    ScaleUI(equalL2.rectTransform, equalDuration);
                    StartCoroutine(TimeUtility.DelayInvoke(equalDuration, () => {
                        var sumDuration = AudioManager.Instance.PlaySound(GetNumVoicePath(CurrentAE.Sum)).Length;
                        ScaleUI(sumL2.rectTransform, sumDuration);
                        StartCoroutine(TimeUtility.DelayInvoke(sumDuration, () => ShowPanelAnswerL2()));
                    }));
                }
            }));
        }));
    }

    void ScaleUI(RectTransform rt, float duration) {
        rt.DOScale(Vector3.one * uiScaleValue, duration).OnComplete(() => {
            rt.DOScale(Vector3.one, duration);
        });
    }

    void ShowSheep(int num) {
        ResetDict();

        for (var i = 0; i < num; i++) {
            var value = Random.Range(0, num);
            SpawnSheep(value % 2 == 0, true);
        }

        StartCoroutine(MoveSheep());
    }

    void ShowSheep(bool isLeft) {
        var num = isLeft ? CurrentAE.LeftValue : CurrentAE.RightValue;

        for (var i = 0; i < num; i++) {
            SpawnSheep(isLeft);
        }

        StartCoroutine(MoveSheep());

        if (isLeft) {
            StartCoroutine(TimeUtility.DelayInvoke(sheepRunTime, () => PlayVoiceRight(plusL1.rectTransform, rightL1.rectTransform, true)));
        } else {
            StartCoroutine(TimeUtility.DelayInvoke(sheepRunTime, () => {
                var duration = AudioManager.Instance.PlaySound(AdditionResPath.VOICE_OPERATOR_EQUAL).Length;
                ScaleUI(equalL1.rectTransform, duration);
                StartCoroutine(TimeUtility.DelayInvoke(duration, () => ShowPanelAnswerL1()));
            }));
        }
    }

    void SpawnSheep(bool isLeft, bool showEffect = false) {
        List<Vector3> keys = isLeft ? _leftKeys : _rightKeys;

        // 移除已被占用的轨道行
        for (var i = 0; i < keys.Count; i++) {
            var key = keys[i];

            if (_dict[key].Count < 1) {
                _dict.Remove(key);
                keys.RemoveAt(i);
            }
        }

        var sheep = CommonUtility.InstantiateFrom(AdditionResPath.SHEEP, spawnParent);
        var row = keys[Random.Range(0, keys.Count)];
        sheep.position = new Vector3(_trackDirection[row] * 1000f, row.y, row.z);  
        sheep.localEulerAngles = Vector3.up * (_trackDirection[row] == 1 ? 180f : 0f);  
        var effect = sheep.Find("Effect");
        var pos = effect.localPosition;
        effect.localPosition = new Vector3(pos.x, pos.y, pos.z * (_trackDirection[row] == 1 ? -1f : 1f));

        if (showEffect) {
            effect.SetActive(true);
        }

        var bodyMat = sheep.Find("Body").GetComponent<Renderer>().material;
        var woolMat = sheep.Find("Wool").GetComponent<Renderer>().material;

        switch (_currentHonourCount) {
            case 0:
                // 全白
                break;
            case 1:
                // 全黑
                bodyMat.mainTexture = _sheepGrayTexture;
                woolMat.mainTexture = _sheepGrayTexture;
                break;
            case 2:
                // 白 + 黑
                if (!isLeft) {
                    bodyMat.mainTexture = _sheepGrayTexture;
                    woolMat.mainTexture = _sheepGrayTexture;
                }
                break;
            case 3:
                // 黑 + 白
                if (isLeft) {
                    bodyMat.mainTexture = _sheepGrayTexture;
                    woolMat.mainTexture = _sheepGrayTexture;
                }
                break;
        }

        var cols = _dict[row];
        var index = Random.Range(0, cols.Count);
        var targetPos = cols[index];

        // 等所有羊被创建后安排其有序开跑
        _moveSheeps.Add(new KeyValuePair<Transform, Vector3>(sheep, targetPos));
        _moveDirections.Add(_trackDirection[row] == 1);

        // 羊被创建后立即开跑
        //sheep.DOMoveX(targetPos.x, sheepRunTime).OnComplete(() => sheep.GetComponent<SheepController>().Idle());

        // 移除被占用的列位置
        cols.RemoveAt(index);
    }

    List<KeyValuePair<Transform, Vector3>> _moveSheeps = new List<KeyValuePair<Transform, Vector3>>();
    List<bool> _moveDirections = new List<bool>();

    IEnumerator MoveSheep() {
        var leftToRights = new List<KeyValuePair<Transform, Vector3>>();
        var rightToLefts = new List<KeyValuePair<Transform, Vector3>>();

        for (var i = 0; i < _moveDirections.Count; i++) {
            if (_moveDirections[i]) {
                leftToRights.Add(_moveSheeps[i]);
            } else {
                rightToLefts.Add(_moveSheeps[i]);
            }
        }

        // left (+X) -> right (-X)，故采用降序
        leftToRights.Sort((lv, rv) => -lv.Value.x.CompareTo(rv.Value.x));

        // right (-X) -> left (+X)，故采用升序
        rightToLefts.Sort((lv, rv) => lv.Value.x.CompareTo(rv.Value.x));

        while (leftToRights.Count > 0 || rightToLefts.Count > 0) {
            yield return new WaitForSeconds(0.5f);

            if (leftToRights.Count > 0) {
                var index = leftToRights.Count - 1;
                var kvp = leftToRights[index];
                var sheep = kvp.Key;
                var targetPos = kvp.Value;
                sheep.DOMoveX(targetPos.x, sheepRunTime).OnComplete(() => sheep.GetComponent<SheepController>().Idle());
                leftToRights.RemoveAt(index);
            }
            
            if (rightToLefts.Count > 0) {
                var index = rightToLefts.Count - 1;
                var kvp = rightToLefts[rightToLefts.Count - 1];
                var sheep = kvp.Key;
                var targetPos = kvp.Value;
                sheep.DOMoveX(targetPos.x, sheepRunTime).OnComplete(() => sheep.GetComponent<SheepController>().Idle());
                rightToLefts.RemoveAt(index);
            }
        }

        _moveSheeps.Clear();
        _moveDirections.Clear();
    }

    void DestroySheep() {
        for (var i = 0; i < spawnParent.childCount; i++) {
            var sheep = spawnParent.GetChild(i);
            sheep.GetComponent<SheepController>().Run();
            sheep.DOLocalMove(sheep.localPosition + (sheep.right * 1000f), sheepRunTime).OnComplete(() => Destroy(sheep.gameObject));
        }
    }

    public string GetNumVoicePath(int num) {
        switch (num) {
            case 1:
                return AdditionResPath.VOICE_NUM_1;
            case 2:
                return AdditionResPath.VOICE_NUM_2;
            case 3:
                return AdditionResPath.VOICE_NUM_3;
            case 4:
                return AdditionResPath.VOICE_NUM_4;
            case 5:
                return AdditionResPath.VOICE_NUM_5;
            case 6:
                return AdditionResPath.VOICE_NUM_6;
            case 7:
                return AdditionResPath.VOICE_NUM_7;
            case 8:
                return AdditionResPath.VOICE_NUM_8;
            case 9:
                return AdditionResPath.VOICE_NUM_9;
            default:
                Debug.LogError("Missing voice...");
                return null;
        }
    }

    bool _isHandling = false;

    public void OnClickBackButton() {
        if (_isHandling) {
            return;
        }

        _isHandling = true;
        GameStateManager.Instance.GotoState(GameStateName.MAIN_STATE);
    }
}
